<!-- 上传组件 -->
<script setup>
import { ref } from 'vue'

import { beforeUpload, afterUpload, cancelUpload } from '@/request/upload'
import { useUserStore, useDataStore, useFilePidStore } from '@/stores/index'
import { enterFolder } from '@/request/common'
import SparkMD5 from 'spark-md5'
import { getUserInfo } from '@/request/usr'

//根据服务端返回的状态码做出反应，默认即可
const fileStatusText = ref({
  success: '完成',
  error: '失败',
  uploading: '上传中',
  paused: '暂停中',
  waiting: '等待中'
})
const autoStart = ref(true) //是否自动上传
const options = ref({
  target: '/prod-api/file/uploadFileChunk', //上传地址
  chunkSize: 1 * 1024 * 256, //1MB  分块，单个数据块的值大小，用于分块上传实现断续重传
  testChunks: false, //是否测试每个块是否在服务端已经上传了，主要用来实现秒传、跨浏览器上传等【一般默认】
  simultaneousUploads: 1, //并发上传数
  fileParameterName: 'fileParams', //上传文件的时候文件的参数名，默认是multipart上传，参数名默认是file
  query: {}, //请求url时候携带的其他参数，json格式
  headers: {}, //设置请求头信息,json格式
  method: 'form', //当前上传文件使用的方式，默认与form表单一样multipart
  prioritizeFirstAndLastChunk: false, //对于文件而言是否高优先级发送第一个和最后一个块。一般用来发送到服务端，然后判断是否是合法文件；例如图片或者视频的 meta 数据一般放在文件第一部分，这样可以根据第一个块就能知道是否支持
  uploadMethod: 'post', //真正上传的时候使用的 HTTP 方法
  // checkChunkUploadedByResponse: () => {
  //   return onFileAdded()
  // },
  processParams(params) {
    // console.log(params.identifier) //每一次分片传给后台的参数，params是该方法返回的形参，包含分片信息
    return {
      //返回一个对象，会添加到每一个分片的请求参数里面
      filename: params.filename,
      fileMd5: params.identifier,
      totalChunks: params.totalChunks,
      chunkNumber: params.chunkNumber,
      filePid: useFilePidStore().uploadingPid,
      userId: useUserStore().UserInfo.userId
    }
  }
})
// const attrs = {
//   accept: 'image/*'
// }
//  计算Md5,生成唯一标识uniqueIdentifier
//上传前发校验!!!!!!!!!!!!!!!!!!!!
//文件添加时回调，这里可以做格式校验，md5计算
//批量
// const onFilesAdded = (files, fileList) => {
//   fileList.forEach((file) => {
//     computeMD5(file)
//   })
//   //计算所以文件的大小
//   const fileSize = fileList.reduce((total, file) => total + file.size, 0)

//   const res = beforeUpload(userId, filePid, fileMd5, fileSize / 1024)
// }

//md5函数
//上传前
const onFileAdded = async (file) => {
  // 计算MD5;
  let fileReader = new FileReader()
  let md5 = ''
  file.pause() //先暂停，后续生成uniqueIdentifier
  fileReader.readAsArrayBuffer(file.file)
  fileReader.onload = async (e) => {
    // @ts-ignore
    if (file.size != e.target.result.byteLength) {
      file.error('文件读取失败')
      return
    }
    md5 = SparkMD5.hash(file.name) //业务需求以文件名作为加密
    file.uniqueIdentifier = md5
    const name = file.name
    const fileSize = file.size / 1024
    const userId = useUserStore().getUserInfo().userId
    const filePid = useFilePidStore().setUploadingPid(useFilePidStore().filePid)
    beforeUpload(userId, filePid, file.uniqueIdentifier, fileSize, name).then(
      (res) => {
        console.log(res)
        // if (res === true) {
        //   // options.value.checkChunkUploadedByResponse = true
        //   // file.uploader.opts.checkChunkUploadedByResponse = true
        //   // console.log(file.uploader.opts.checkChunkUploadedByResponse)
        //   return true
        // }
        if (res.code === 500) {
          file.cancel()
        } else if (md5 != '') {
          file.resume() //继续上传文件
        }
      }
    )
  }
  fileReader.onerror = function () {
    file.error('文件读取失败')
  }

  // console.log(res)
}
//上传完成后
//所有分片上传完成的回调，需要注意的是，由于异步上传，每一次分片上传不会等上一次响应回来才发送，
//因此该上传成功的回调时，返回的分片响应可能不是最后一片，因此后续会发送合并请求告诉后台进行合并文件chunk
const onFileSuccess = async (rootFile, file, message) => {
  //所有分片上传成功，发送合并分片请求，具体参数与后台确定，后台合并文件++++++++++
  // console.log(file, message, chunk)
  const fileMd5 = rootFile.uniqueIdentifier
  const totalChunks = file.chunks.length
  const fileName = file.name

  // console.log(file, chunk)
  const res = JSON.parse(message)
  // console.log(res)
  if (res.code === 200) {
    const userId = useUserStore().getUserInfo().userId
    const filePid = useFilePidStore().filePid
    await afterUpload(userId, filePid, fileMd5, fileName, totalChunks).then(
      () => {
        // console.log(res)
        getUserInfo(useUserStore().UserInfo.userId).then((res) => {
          useUserStore().setUserInfo(res)
        })
      }
    )
    //刷新
    enterFolder(useFilePidStore().filePid).then((res) => {
      useDataStore().setData(res.data)
    })
  }
}

//移除回调!!!!!!!!!!!!!!
const onFileRemoved = (file) => {
  const fileMd5 = file.uniqueIdentifier
  ///用户id,文件
  const userId = useUserStore().getUserInfo().userId
  const filePid = useUserStore().getUserInfo().filePid
  // const res =
  cancelUpload(userId, filePid, fileMd5)
  // console.log(res)
}

//文件上传的过程中会频繁调用该函数const onFileProgress = (rootFile, file, chunk) => {}
const onFileProgress = () => {}

//文件上传出错的回调const onFileError = (rootFile, file, msg, chunk) => {}
const onFileError = () => {}
</script>
<template>
  <!--     @files-added="onFilesAdded" -->
  <uploader
    :options="options"
    :fileStatusText="fileStatusText"
    :autoStart="autoStart"
    @file-added="onFileAdded"
    @file-success="onFileSuccess"
    @file-progress="
      // @ts-ignore
      onFileProgress(rootFile, file, chunk)
    "
    @file-error="
      // @ts-ignore
      onFileError(file)
    "
    @file-removed="
      // @ts-ignore
      onFileRemoved(rootFile, file, message, chunk)
    "
    ref="uploaderClass"
    style="width: 100%"
    class="uploader-exmple"
  >
    <uploader-unsupport></uploader-unsupport>
    <uploader-drop class="el-upload-list__item">
      <!-- 上传提示 -->
      <!-- <h3>请添加你想要上传的文件</h3> -->
      <!-- 选择文件 -->
      <!-- <uploader-btn class="el-button el-button--primary">选择文件</uploader-btn> -->
      <!-- 选择图片 -->
      <!-- <uploader-btn class="el-button el-button--primary" :attrs="attrs">
        <span>选择图片</span>
      </uploader-btn> -->
      <!-- 选择文件夹 -->
      <uploader-btn class="upload-button" style="">
        <el-icon size="100">
          <UploadFilled />
        </el-icon>
        <span>点击此处上传文件或将文件拖拽到此处</span>
      </uploader-btn>
      <!-- <div style="width: 100%; height: 20vh; background-color: aqua">
      
      </div> -->
      <!-- <uploader-btn class="el-button el-button--primary" :directory="true">
        <span>选择文件夹</span>
      </uploader-btn> -->
    </uploader-drop>
    <uploader-list class="el-upload-list__item">
      <!-- <template v-slot="props">
        <ul>
          <li v-for="file in props.fileList" :key="file.id">
            <uploader-file
              :file="file"
              :list="true"
              ref="uploaderFile"
              :pauseFlag="pauseFlag"
            >
              <template v-slot="props">
                //使用插槽替换组件默认样式
                <div class="filebox">
                  <p class="fileNameBox">
                    <span class="fileIcon"></span>
                    {{ file.name }}
                  </p>
                  <p class="fileProgressBox">
                    <progress
                      class="progressLength"
                      :percentage="
                        parseInt(
                          props.progress.toFixed(2) * 100 - 1 < 0
                            ? 0
                            : props.progress.toFixed(2) * 100 - 1
                        )
                      "
                    ></progress>
                    <span
                      :class="{ statusBtn: !pauseFlag, resumeBtn: pauseFlag }"
                      class="progressBtn"
                      @click="pause(file, file.resourceId)"
                    ></span>
                    <span
                      class="cancelBtn progressBtn"
                      @click="remove(file, file.resourceId)"
                    ></span>
                  </p>
                  <p class="fileInfoBox">
                    <span class="fileInfoItem"
                      >速度：{{
                        pauseFlag ? 0 : props.formatedAverageSpeed
                      }}</span
                    >
                    <span class="fileInfoItem"
                      >已上传：{{
                        (
                          parseFloat(props.formatedSize) * props.progress
                        ).toFixed(1)
                      }}/{{ props.formatedSize }}</span
                    >
                    <span class="fileInfoItem"
                      >剩余时间：{{
                        pauseFlag ? 0 : props.formatedTimeRemaining
                      }}</span
                    >
                  </p>
                </div>
              </template>
            </uploader-file>
          </li>
        </ul>
      </template> -->
    </uploader-list>
  </uploader>
</template>

<style lang="scss" scoped>
.upload-button {
  height: 20vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: rgb(255, 255, 255);
  border: 0;
  border: 2px solid var(--el-border-color);
  transition: all 0.2s;
}
.upload-button:hover {
  border: 2px dashed var(--el-border-color);
}
</style>
